package com.sk.weichat.mvp.presenter;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.sk.weichat.AppConstant;
import com.sk.weichat.R;
import com.sk.weichat.Reporter;
import com.sk.weichat.audio_x.VoicePlayer;
import com.sk.weichat.bean.Contacts;
import com.sk.weichat.bean.Friend;
import com.sk.weichat.bean.PrivacySetting;
import com.sk.weichat.bean.PublicMenu;
import com.sk.weichat.bean.User;
import com.sk.weichat.bean.VideoFile;
import com.sk.weichat.bean.collection.CollectionEvery;
import com.sk.weichat.bean.message.ChatMessage;
import com.sk.weichat.bean.message.XmppMessage;
import com.sk.weichat.bean.redpacket.OpenRedpacket;
import com.sk.weichat.db.InternationalizationHelper;
import com.sk.weichat.db.dao.ChatMessageDao;
import com.sk.weichat.db.dao.FriendDao;
import com.sk.weichat.helper.DialogHelper;
import com.sk.weichat.helper.FileDataHelper;
import com.sk.weichat.helper.PrivacySettingHelper;
import com.sk.weichat.helper.UploadEngine;
import com.sk.weichat.mvp.contract.ChatContract;
import com.sk.weichat.ui.base.CoreManager;
import com.sk.weichat.ui.me.redpacket.MucRedPacketDetailsActivity;
import com.sk.weichat.ui.mucfile.XfileUtils;
import com.sk.weichat.util.AsyncUtils;
import com.sk.weichat.util.MediaFile;
import com.sk.weichat.util.PreferenceUtils;
import com.sk.weichat.util.StringUtils;
import com.sk.weichat.util.TimeUtils;
import com.sk.weichat.util.ToastUtil;
import com.sk.weichat.xmpp.listener.ChatMessageListener;
import com.xuan.xuanhttplibrary.okhttp.HttpUtils;
import com.xuan.xuanhttplibrary.okhttp.callback.BaseCallback;
import com.xuan.xuanhttplibrary.okhttp.callback.ListCallback;
import com.xuan.xuanhttplibrary.okhttp.result.ArrayResult;
import com.xuan.xuanhttplibrary.okhttp.result.ObjectResult;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import fm.jiecao.jcvideoplayer_lib.JCVideoPlayer;
import okhttp3.Call;
import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;

/**
 * 聊天界面底部逻辑处理器
 * create swy
 */
public class ChatBottomPresenter implements ChatContract.BottomPresenter {

    private final ChatContract.ChatView mChatView;
    private final CoreManager mCoreManager;
    private final Context mContext;
    private Friend mFriend;
    private String mLoginUserId;
    private List<ChatMessage> mChatMessages;
    private String mLoginNickName;
    private int isReadDel;

    public void setReadDel(int readDel) {
        isReadDel = readDel;
    }

    public ChatBottomPresenter(ChatContract.ChatView chatView, CoreManager coreManager) {
        this.mChatView = chatView;
        mContext = (Context) chatView;
        this.mCoreManager = coreManager;

    }

    public void bandData(Friend friend, String loginUserId, String loginNickName, List<ChatMessage> chatMessages) {
        mFriend = friend;
        mLoginUserId = loginUserId;
        mLoginNickName = loginNickName;
        mChatMessages = chatMessages;

    }

    /**
     * 发送文件
     *
     * @param file 文件
     */
    public void sendFile(File file) {
        if (!file.exists()) {
            return;
        }
        if (isAuthenticated()) {
            return;
        }
        long fileSize = file.length();
        ChatMessage message = new ChatMessage();
        message.setType(XmppMessage.TYPE_FILE);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        message.setContent("");
        message.setTimeSend(TimeUtils.sk_time_current_time());
        String filePath = file.getAbsolutePath();
        message.setFilePath(filePath);
        message.setFileSize((int) fileSize);
        String suffix = "";
        try {
            suffix = filePath.substring(filePath.lastIndexOf(".") + 1);
        } catch (Exception e) {

        }
        if (suffix.equalsIgnoreCase("jpg") || suffix.equalsIgnoreCase("jpeg") || suffix.equalsIgnoreCase("png") || suffix.equalsIgnoreCase("gif")) {
            //发送的文件属于图片
            int[] imageParam = FileDataHelper.getImageParamByIntsFile(filePath);
            message.setLocation_x(String.valueOf(imageParam[0]));
            message.setLocation_y(String.valueOf(imageParam[1]));
        }
        mChatMessages.add(message);
        mChatView.updateContent(true);
        sendMessage(message);
    }

    /**
     * 发送文本
     *
     * @param text 文本
     */
    public void sendText(String text, ChatMessage replayMessage) {
        if (TextUtils.isEmpty(text)) {
            return;
        }
        if (isAuthenticated()) {
            return;
        }

        ChatMessage message = new ChatMessage();
        // 文本类型
        message.setType(XmppMessage.TYPE_TEXT);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        message.setContent(text);
        if (replayMessage != null) {
            message.setType(XmppMessage.TYPE_REPLAY);
            message.setObjectId(replayMessage.toJsonString());
            mChatView.onSendMessageReplay();
        }
        message.setIsReadDel(isReadDel);
        mChatMessages.add(message);
        mChatView.updateContent(true);

        sendMessage(message);
        // 遍历消息集合，查询红包类型消息
        for (ChatMessage msg : mChatMessages) {
            if (msg.getType() == XmppMessage.TYPE_RED// 红包
                    && StringUtils.strEquals(msg.getFilePath(), "3")// 口令红包
                    && text.equalsIgnoreCase(msg.getContent())// 发送的文本与口令一致
                    && msg.getFileSize() == 1// 可以领取的状态
                    && !msg.isMySend()) {
                mChatView.showRedDialog(msg);
            }
        }
    }

    /**
     * 发送照片
     *
     * @param text
     */
    public void sendGif(String text) {
        if (TextUtils.isEmpty(text)) {
            return;
        }
        if (isAuthenticated()) {
            return;
        }
        ChatMessage message = new ChatMessage();
        message.setType(XmppMessage.TYPE_GIF);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        message.setContent(text);
        mChatMessages.add(message);
        sendMessage(message);
        mChatView.updateContent(true);
    }

    /**
     * 发送收藏
     *
     * @param collection 收藏链接
     */
    public void sendCollection(String collection) {
        if (isAuthenticated()) {
            return;
        }
        ChatMessage message = new ChatMessage();
        message.setType(XmppMessage.TYPE_IMAGE);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        message.setContent(collection);
        message.setUpload(true);// 自定义表情，不需要上传
        message.setIsReadDel(isReadDel);
        mChatMessages.add(message);
        sendMessage(message);
        mChatView.updateContent(true);
    }

    public void clickShake() {
        if (isAuthenticated()) {
            return;
        }
        ChatMessage message = new ChatMessage();
        message.setType(XmppMessage.TYPE_SHAKE);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        message.setContent(mContext.getString(R.string.msg_shake));
        mChatMessages.add(message);
        sendMessage(message);
        mChatView.updateContent(true);
        mChatView.onShake(0);// 戳一戳动画
    }

    public void sendVoice(String filePath, int timeLen) {
        if (TextUtils.isEmpty(filePath)) {
            return;
        }
        if (isAuthenticated()) {
            return;
        }
        File file = new File(filePath);
        long fileSize = file.length();
        ChatMessage message = new ChatMessage();
        message.setType(XmppMessage.TYPE_VOICE);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        message.setContent("");
        message.setFilePath(filePath);
        message.setFileSize((int) fileSize);
        message.setTimeLen(timeLen);
        message.setIsReadDel(isReadDel);
        mChatMessages.add(message);
        sendMessage(message);
        mChatView.updateContent(true);
    }

    public void sendImage(File file) {
        if (!file.exists()) {
            return;
        }
        if (isAuthenticated()) {
            return;
        }
        long fileSize = file.length();
        ChatMessage message = new ChatMessage();
        message.setType(XmppMessage.TYPE_IMAGE);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        message.setContent("");
        String filePath = file.getAbsolutePath();
        message.setFilePath(filePath);
        message.setFileSize((int) fileSize);
        int[] imageParam = FileDataHelper.getImageParamByIntsFile(filePath);
        message.setLocation_x(String.valueOf(imageParam[0]));
        message.setLocation_y(String.valueOf(imageParam[1]));
        message.setIsReadDel(isReadDel);
        mChatMessages.add(message);
        sendMessage(message);
        mChatView.updateContent(true);
    }

    public void sendVideo(File file) {
        if (!file.exists()) {
            return;
        }
        if (isAuthenticated()) {
            return;
        }
        long fileSize = file.length();
        ChatMessage message = new ChatMessage();
        message.setType(XmppMessage.TYPE_VIDEO);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        message.setContent("");
        String filePath = file.getAbsolutePath();
        message.setFilePath(filePath);
        message.setFileSize((int) fileSize);
        message.setIsReadDel(isReadDel);
        mChatMessages.add(message);
        sendMessage(message);
        mChatView.updateContent(true);
    }

    public void sendContacts(List<Contacts> contactsList, ChatMessage replayMessage) {
        for (Contacts contacts : contactsList) {
            sendText(contacts.getName() + '\n' + contacts.getTelephone(), replayMessage);
        }
    }

    public void sendLocate(double latitude, double longitude, String address, String snapshot) {
        if (isAuthenticated()) {
            return;
        }
        ChatMessage message = new ChatMessage();
        message.setType(XmppMessage.TYPE_LOCATION);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        // 上传图片后会给赋值，
        message.setContent("");
        message.setFilePath(snapshot);
        message.setLocation_x(latitude + "");
        message.setLocation_y(longitude + "");
        message.setObjectId(address);
        mChatMessages.add(message);
        sendMessage(message);
        mChatView.updateContent(true);
    }

    public void clickCollectionSend(int type, String content, int timeLen, String filePath, long fileSize) {
        if (isAuthenticated()) {
            return;
        }

        if (TextUtils.isEmpty(content)) {
            return;
        }
        ChatMessage message = new ChatMessage();
        message.setType(type);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        message.setContent(content);
        message.setTimeLen(timeLen);
        message.setFileSize((int) fileSize);
        message.setUpload(true);
        if (!TextUtils.isEmpty(filePath)) {
            message.setFilePath(filePath);
        }
        message.setIsReadDel(0);
        mChatMessages.add(message);
        sendMessage(message);
        mChatView.updateContent(true);
    }

    public void clickCollectionSend(CollectionEvery collection, ChatMessage replayMessage) {
        // 不管什么收藏消息类型，都可能有文字，单独发一条文字消息，
        if (!TextUtils.isEmpty(collection.getCollectContent())) {
            sendText(collection.getCollectContent(), replayMessage);
        }
        int type = collection.getXmppType();
        if (type == XmppMessage.TYPE_TEXT) {
            // 文字消息发出了文字就可以结束了，
            return;
        } else if (type == XmppMessage.TYPE_IMAGE) {
            // 图片可能有多张，分开发送，
            String allUrl = collection.getUrl();
            for (String url : allUrl.split(",")) {
                clickCollectionSend(type, url, collection.getFileLength(), collection.getFileName(), collection.getFileSize());
            }
            return;
        }
        clickCollectionSend(type, collection.getUrl(), collection.getFileLength(), collection.getFileName(), collection.getFileSize());
    }

    public void sendCard(Friend friend) {
        if (isAuthenticated()) {
            return;
        }
        ChatMessage message = new ChatMessage();
        message.setType(XmppMessage.TYPE_CARD);
        message.setFromUserId(mLoginUserId);
        message.setFromUserName(mLoginNickName);
        message.setContent(friend.getNickName());
        message.setObjectId(friend.getUserId());
        mChatMessages.add(message);
        sendMessage(message);
        mChatView.updateContent(true);
    }

    /**
     * @author: czl
     * @description 余额发红包
     * @date: 2019/10/10 16:39
     */
    public void sendRed(final String type, String money, String count, final String words, String payPassword) {
//        if (isAuthenticated()) {
//            return;
//        }
//        Map<String, String> params = new HashMap();
//        params.put("access_token", mCoreManager.getSelfStatus().accessToken);
//        params.put("type", type);
//        params.put("moneyStr", money);
//        params.put("count", count);
//        params.put("greetings", words);
//        params.put("toUserId", mFriend.getUserId());
//
//        HttpUtils.get().url(mCoreManager.getConfig().REDPACKET_SEND)
//                .params(params)
//                .addSecret(payPassword, money)
//                .build()
//                .execute(new BaseCallback<RedPacketBean>(RedPacketBean.class) {
//
//                    @Override
//                    public void onResponse(ObjectResult<RedPacketBean> result) {
//                        RedPacketBean redPacketBean = result.getData();
//                        if (result.getResultCode() != 1) {
//                            // 发送红包失败，
//                            ToastUtil.showToast(mContext, result.getResultMsg());
//                        } else {
//                            String objectId = redPacketBean.getId();
//                            ChatMessage message = new ChatMessage();
//                            message.setType(XmppMessage.TYPE_RED);
//                            message.setFromUserId(mLoginUserId);
//                            message.setFromUserName(mLoginNickName);
//                            message.setContent(words); // 祝福语
//                            message.setFilePath(type); // 用FilePath来储存红包类型
//                            message.setFileSize(redPacketBean.getStatus()); //用filesize来储存红包状态
//                            message.setObjectId(objectId); // 红包id
//                            mChatMessages.add(message);
//                            sendMessage(message);
//                            mChatView.updateContent(true);
//                            // 更新余额
//                            CoreManager.updateMyBalance();
//                        }
//                    }
//
//                    @Override
//                    public void onError(Call call, Exception e) {
//                    }
//                });
    }


    public void clickVideo(Intent data) {
        if (data == null) {
            return;
        }
        String json = data.getStringExtra(AppConstant.EXTRA_VIDEO_LIST);
        List<VideoFile> fileList = JSON.parseArray(json, VideoFile.class);
        if (fileList == null || fileList.size() == 0) {
            // 不可到达，列表里有做判断，
            Reporter.unreachable();
        } else {
            for (VideoFile videoFile : fileList) {
                String filePath = videoFile.getFilePath();
                if (TextUtils.isEmpty(filePath)) {
                    // 不可到达，列表里有做过滤，
                    Reporter.unreachable();
                } else {
                    File file = new File(filePath);
                    if (!file.exists()) {
                        // 不可到达，列表里有做过滤，
                        Reporter.unreachable();
                    } else {
                        sendVideo(file);
                    }
                }
            }
        }
    }

    /**
     * 选择位置
     *
     * @param data
     */
    public void clickLocate(Intent data) {
        double latitude = data.getDoubleExtra(AppConstant.EXTRA_LATITUDE, 0);
        double longitude = data.getDoubleExtra(AppConstant.EXTRA_LONGITUDE, 0);
        String address = data.getStringExtra(AppConstant.EXTRA_ADDRESS);
        String snapshot = data.getStringExtra(AppConstant.EXTRA_SNAPSHOT);

        if (latitude != 0 && longitude != 0 && !TextUtils.isEmpty(address)
                && !TextUtils.isEmpty(snapshot)) {
            sendLocate(latitude, longitude, address, snapshot);
        } else {
            // ToastUtil.showToast(mContext, "请把定位开启!");
            mChatView.showToastMsg(InternationalizationHelper.getString("JXLoc_StartLocNotice"));
        }
    }

    /**
     * 点击感叹号重新发送
     */
    public void sendAgain(ChatMessage message) {
        if (message.getType() == XmppMessage.TYPE_VOICE || message.getType() == XmppMessage.TYPE_IMAGE
                || message.getType() == XmppMessage.TYPE_VIDEO || message.getType() == XmppMessage.TYPE_FILE
                || message.getType() == XmppMessage.TYPE_LOCATION) {
            if (!message.isUpload()) {
                // 将需要上传的消息状态置为发送中，防止在上传的时候退出当前界面，回来后[还未上传成功]读取数据库又变为了感叹号
                ChatMessageDao.getInstance().updateMessageSendState(mLoginUserId, mFriend.getUserId(),
                        message.get_id(), ChatMessageListener.MESSAGE_SEND_ING);
                UploadEngine.uploadImFile(mCoreManager.getSelfStatus().accessToken, mCoreManager.getSelf().getUserId(), mFriend.getUserId(), message, mUploadResponse);
            } else {
                if (isAuthenticated()) {
                    return;
                }
                mCoreManager.sendChatMessage(mFriend.getUserId(), message);
            }
        } else {
            if (isAuthenticated()) {
                return;
            }
            mCoreManager.sendChatMessage(mFriend.getUserId(), message);
        }
    }

    /**
     * 发送一条包装好的消息
     */
    public void sendMessage(final ChatMessage message) {
        if (isInBlackList()) {// 该用户在你的黑名单列表内
            mChatView.showToastMsg("对方已被你拉黑，不能发消息给Ta");
            // 移除掉该条消息
            mChatMessages.remove(message);
            mChatView.updateContent(true);
            return;
        }

        message.setFromUserId(mLoginUserId);
        PrivacySetting privacySetting = PrivacySettingHelper.getPrivacySettings(mContext);
        boolean isSupport = privacySetting.getMultipleDevices() == 1;
        if (isSupport) {
            message.setFromId("youjob");
        } else {
            message.setFromId("youjob");
        }
        if (mFriend.getIsDevice() == 1) {
            message.setToUserId(mLoginUserId);
            message.setToId(mFriend.getUserId());
        } else {
            message.setToUserId(mFriend.getUserId());

            // sz 消息过期时间
            if (mFriend.getChatRecordTimeOut() == -1 || mFriend.getChatRecordTimeOut() == 0) {// 永久
                message.setDeleteTime(-1);
            }else if(mFriend.getChatRecordTimeOut() == -2){//不同步改为一周
                long deleteTime = TimeUtils.sk_time_current_time() + (long) (7 * 24 * 60 * 60);
                message.setDeleteTime(deleteTime);
            } else {
                long deleteTime = TimeUtils.sk_time_current_time() + (long) (mFriend.getChatRecordTimeOut() * 24 * 60 * 60);
                message.setDeleteTime(deleteTime);
            }
        }

        boolean isEncrypt = privacySetting.getIsEncrypt() == 1;
        if (isEncrypt) {
            message.setIsEncrypt(1);
        } else {
            message.setIsEncrypt(0);
        }

        message.setReSendCount(ChatMessageDao.fillReCount(message.getType()));
        message.setPacketId(UUID.randomUUID().toString().replaceAll("-", ""));
        message.setTimeSend(TimeUtils.sk_time_current_time());

        //未回复消息，即打招呼消息
        if (mFriend.getReplyStatus() == Friend.STATUS_REPLAY_NONE) {
            if (message.getType() == XmppMessage.TYPE_IMAGE
                    || message.getType() == XmppMessage.TYPE_VIDEO || message.getType() == XmppMessage.TYPE_FILE) {// 语音、图片、视频、文件不能发送

                message.setMessageState(ChatMessageListener.MESSAGE_SEND_OVER);
            }
        }
        //非好友不能发语音
        if (mFriend.getStatus() != Friend.STATUS_FRIEND && mFriend.getStatus() != Friend.STATUS_SYSTEM && message.getType() == XmppMessage.TYPE_VOICE) {
            message.setMessageState(ChatMessageListener.MESSAGE_SEND_OVER);
        }

        // 将消息保存在数据库了
        ChatMessageDao.getInstance().saveNewSingleChatMessage(mLoginUserId, mFriend.getUserId(), message);
        if (message.getType() == XmppMessage.TYPE_VOICE || message.getType() == XmppMessage.TYPE_IMAGE
                || message.getType() == XmppMessage.TYPE_VIDEO || message.getType() == XmppMessage.TYPE_FILE
                || message.getType() == XmppMessage.TYPE_LOCATION) {// 语音、图片、视频、文件需要上传在发送
            // 位置消息也要上传截图，
            if (!message.isUpload()) {// 未上传
                if (mFriend.getIsDevice() == 1) {
                    // 我的设备会出问题
                    // UploadEngine.uploadImFile(coreManager.getSelfStatus().accessToken, coreManager.getSelf().getUserId(), userId, message, mUploadResponse);
                    UploadEngine.uploadImFile(mCoreManager.getSelfStatus().accessToken, mCoreManager.getSelf().getUserId(), mFriend.getUserId(), message, mUploadResponse);
                } else {
                    UploadEngine.uploadImFile(mCoreManager.getSelfStatus().accessToken, mCoreManager.getSelf().getUserId(), mFriend.getUserId(), message, mUploadResponse);
                }
            } else {// 已上传 自定义表情默认为已上传
                sendMsg(message);
            }
        } else {// 其他类型直接发送
            sendMsg(message);
        }
    }

    private void sendMsg(ChatMessage message) {
        // 一些异步回调进来的也要判断xmpp是否在线，
        // 比如图片上传成功后，

        if (mFriend.getStatus() != Friend.STATUS_FRIEND && mFriend.getStatus() != Friend.STATUS_SYSTEM
                && mFriend.getReplyStatus() == Friend.STATUS_REPLAY_NONE) {//未回复消息，即打招呼消息
            if (message.getType() == XmppMessage.TYPE_IMAGE
                    || message.getType() == XmppMessage.TYPE_VIDEO || message.getType() == XmppMessage.TYPE_FILE) {// 语音、图片、视频、文件不能发送
                String content = "";
                switch (message.getType()) {

                    case XmppMessage.TYPE_IMAGE:
                        content = "图片发送失败，对方回复后才能使用图片功能";
                        break;
                    case XmppMessage.TYPE_VIDEO:
                        content = "视频发送失败，对方回复后才能使用视频功能";
                        break;
                    case XmppMessage.TYPE_FILE:
                        content = "文件发送失败，对方回复后才能使用文件功能";
                        break;
                }

                //本地添加一个系统提示信息
                FriendDao.getInstance().addUnReplayInMsgTable(mLoginUserId, message.getToUserId(), content);

                ChatMessage chatMessage = new ChatMessage();
                chatMessage.setType(XmppMessage.TYPE_TIP);
                chatMessage.setFromUserId(mLoginUserId);
                chatMessage.setContent(content);
                chatMessage.setMessageState(ChatMessageListener.MESSAGE_SEND_OVER);
                chatMessage.setMySend(false);// 表示不是自己发的
                chatMessage.setPacketId(UUID.randomUUID().toString().replaceAll("-", ""));// 随机产生一个PacketId
                chatMessage.setTimeSend(TimeUtils.sk_time_current_time());
                mChatMessages.add(chatMessage);
                mChatView.updateContent(true);
                return;
            } else {
                message.setMsgType(ChatMessage.TYPE_HELLO);
            }
        } else if (mFriend.getStatus() != Friend.STATUS_FRIEND && mFriend.getStatus() != Friend.STATUS_SYSTEM
                && mFriend.getReplyStatus() == Friend.STATUS_REPLAY_SINGLE) {//对方已经单方面发送了打招呼消息
            message.setMsgType(ChatMessage.TYPE_HELLO);
        }

        //非好友不能发送语音消息
        if (mFriend.getStatus() != Friend.STATUS_FRIEND && mFriend.getStatus() != Friend.STATUS_SYSTEM) {
            if (message.getType() == XmppMessage.TYPE_VOICE) {
                String content = "互为好友才能发送语音";
                //本地添加一个系统提示信息
                FriendDao.getInstance().addUnReplayInMsgTable(mLoginUserId, message.getToUserId(), content);

                ChatMessage chatMessage = new ChatMessage();
                chatMessage.setType(XmppMessage.TYPE_TIP);
                chatMessage.setFromUserId(mLoginUserId);
                chatMessage.setContent(content);
                chatMessage.setMessageState(ChatMessageListener.MESSAGE_SEND_OVER);
                chatMessage.setMySend(false);// 表示不是自己发的
                chatMessage.setPacketId(UUID.randomUUID().toString().replaceAll("-", ""));// 随机产生一个PacketId
                chatMessage.setTimeSend(TimeUtils.sk_time_current_time());
                mChatMessages.add(chatMessage);
                mChatView.updateContent(true);
                return;
            }
        }

        if (isAuthenticated()) {
            return;
        }
        if (mFriend.getIsDevice() == 1) {
            mCoreManager.sendChatMessage(mLoginUserId, message);
        } else {
            mCoreManager.sendChatMessage(mFriend.getUserId(), message);
        }
    }

    /**
     * 打开红包
     */
    public void openRedPacket(final ChatMessage message) {
        HashMap<String, String> params = new HashMap<String, String>();
        String redId = message.getObjectId();
        params.put("access_token", mCoreManager.getSelfStatus().accessToken);
        params.put("id", redId);

        HttpUtils.get().url(mCoreManager.getConfig().REDPACKET_OPEN)
                .params(params)
                .build()
                .execute(new BaseCallback<OpenRedpacket>(OpenRedpacket.class) {

                    @Override
                    public void onResponse(ObjectResult<OpenRedpacket> result) {
                        mChatView.closeRedDialog();
                        if (result.getData() != null) {
                            // 标记已经领取过了一次,不可再领取
                            message.setFileSize(2);
                            ChatMessageDao.getInstance().updateChatMessageReceiptStatus(mLoginUserId, mFriend.getUserId(), message.getPacketId());
                            mChatView.updateContent(false);

                            OpenRedpacket openRedpacket = result.getData();
                            Bundle bundle = new Bundle();
                            Intent intent = new Intent(mContext, MucRedPacketDetailsActivity.class);
                            bundle.putSerializable("openRedpacket", openRedpacket);
                            bundle.putInt("redAction", 1);
                            bundle.putInt("timeOut", 0);

                            bundle.putBoolean("isGroup", false);
                            bundle.putString("mToUserId", mFriend.getUserId());
                            intent.putExtras(bundle);
                            mContext.startActivity(intent);
                            // 更新余额
                            mCoreManager.updateMyBalance();

                            showReceiverRedLocal(openRedpacket);
                        } else {
                            Toast.makeText(mContext, result.getResultMsg(), Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onError(Call call, Exception e) {
                        mChatView.closeRedDialog();
                    }
                });
    }


    // 查看红包领取详情
    public void showRedReceivedDetail(String redId) {
        HashMap<String, String> params = new HashMap<>();
        params.put("access_token", CoreManager.requireSelfStatus(mContext).accessToken);
        params.put("id", redId);

        // TODO: 2019/6/13
        HttpUtils.get().url(CoreManager.requireConfig(mContext).RENDPACKET_GET)
                .params(params)
                .build()
                .execute(new BaseCallback<OpenRedpacket>(OpenRedpacket.class) {

                    @Override
                    public void onResponse(ObjectResult<OpenRedpacket> result) {
                        if (result.getData() != null) {
                            // 当resultCode==1时，表示可领取
                            // 当resultCode==0时，表示红包已过期、红包已退回、红包已领完
                            OpenRedpacket openRedpacket = result.getData();
                            Bundle bundle = new Bundle();
                            Intent intent = new Intent(mContext, MucRedPacketDetailsActivity.class);
                            bundle.putSerializable("openRedpacket", openRedpacket);
                            bundle.putInt("redAction", 0);
                            if (!TextUtils.isEmpty(result.getResultMsg())) //resultMsg不为空表示红包已过期
                            {
                                bundle.putInt("timeOut", 1);
                            } else {
                                bundle.putInt("timeOut", 0);
                            }

                            bundle.putBoolean("isGroup", false);
                            bundle.putString("mToUserId", mFriend.getUserId());
                            intent.putExtras(bundle);
                            mContext.startActivity(intent);
                        } else {
                            Toast.makeText(mContext, result.getResultMsg(), Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onError(Call call, Exception e) {
                    }
                });
    }

    public void clickReplay(ChatMessage message) {
        ChatMessage replayMessage = new ChatMessage(message.getObjectId());
        AsyncUtils.doAsync(this, t -> {
            Reporter.post("查询被回复的消息出错<" + message.getObjectId() + ">", t);
        }, c -> {
            List<ChatMessage> chatMessages = ChatMessageDao.getInstance().searchFromMessage(mContext, mLoginUserId, mFriend.getUserId(), replayMessage);
            if (chatMessages == null) {
                // 没查到消息，
                Log.e("Replay", "本地没有查到被回复的消息<" + message.getObjectId() + ">");
                return;
            }
            int index = -1;
            for (int i = 0; i < chatMessages.size(); i++) {
                ChatMessage m = chatMessages.get(i);
                if (TextUtils.equals(m.getPacketId(), replayMessage.getPacketId())) {
                    index = i;
                }
            }
            if (index == -1) {
                Reporter.unreachable();
                return;
            }
            int finalIndex = index;
            c.uiThread(r -> {
                mChatMessages.clear();
                mChatMessages.addAll(chatMessages);
                mChatView.updateContent(finalIndex);
            });
        });
    }

    /**
     * 撤回消息
     *
     * @param chatMessage
     * @param position
     */
    public void messageBack(final ChatMessage chatMessage, final int position) {
        DialogHelper.showMessageProgressDialog(mContext, InternationalizationHelper.getString("MESSAGE_REVOCATION"));
        Map<String, String> params = new HashMap<>();
        params.put("access_token", mCoreManager.getSelfStatus().accessToken);
        params.put("messageId", chatMessage.getPacketId());
        params.put("delete", "2");  // 1单方删除 2-双方删除
        params.put("type", "1");    // 1单聊记录 2-群聊记录

        // TODO: 2019/6/13
        HttpUtils.get().url(mCoreManager.getConfig().USER_DEL_CHATMESSAGE)
                .params(params)
                .build()
                .execute(new BaseCallback<Void>(Void.class) {

                    @Override
                    public void onResponse(ObjectResult<Void> result) {
                        DialogHelper.dismissProgressDialog();
                        if (chatMessage.getType() == XmppMessage.TYPE_VOICE) {// 撤回的为语音消息，停止播放
                            if (VoicePlayer.instance().getVoiceMsgId().equals(chatMessage.getPacketId())) {
                                VoicePlayer.instance().stop();
                            }
                        } else if (chatMessage.getType() == XmppMessage.TYPE_VIDEO) {
                            JCVideoPlayer.releaseAllVideos();
                        }
                        // 发送撤回消息
                        ChatMessage message = new ChatMessage();
                        message.setType(XmppMessage.TYPE_BACK);
                        message.setFromUserId(mLoginUserId);
                        message.setFromUserName(mCoreManager.getSelf().getNickName());
                        message.setToUserId(mFriend.getUserId());
                        message.setContent(chatMessage.getPacketId());
                        message.setTimeSend(TimeUtils.sk_time_current_time());
                        message.setPacketId(UUID.randomUUID().toString().replaceAll("-", ""));
                        mCoreManager.sendChatMessage(mFriend.getUserId(), message);
                        ChatMessage chat = mChatMessages.get(position);
                        ChatMessageDao.getInstance().updateMessageBack(mLoginUserId, mFriend.getUserId(), chat.getPacketId(), mContext.getString(R.string.you));
                        chat.setType(XmppMessage.TYPE_TIP);
                        //  chat.setContent("你撤回了一条消息");
                        chat.setContent(InternationalizationHelper.getString("JX_AlreadyWithdraw"));
                        //更新单条消息内容
                        mChatView.updateContent(position);
                    }

                    @Override
                    public void onError(Call call, Exception e) {
                        DialogHelper.dismissProgressDialog();
                        ToastUtil.showErrorNet(mContext);
                    }
                });
    }


    public void saveContent(String str) {

        // 清除 回车与空格
        str = str.replaceAll("\\s", "");
        str = str.replaceAll("\\n", "");
        if (TextUtils.isEmpty(str)) {
            if (XfileUtils.isNotEmpty(mChatMessages) && mChatMessages.size() > 1) {
                ChatMessage chat = mChatMessages.get(mChatMessages.size() - 1);
                if (chat.getType() == XmppMessage.TYPE_TEXT && chat.getIsReadDel()) {
                    FriendDao.getInstance().updateFriendContent(
                            mLoginUserId,
                            mFriend.getUserId(),
                            "点击查看",
                            chat.getType(),
                            chat.getTimeSend());
                } else {
                    FriendDao.getInstance().updateFriendContent(
                            mLoginUserId,
                            mFriend.getUserId(),
                            chat.getContent(),
                            chat.getType(),
                            chat.getTimeSend());
                }
            }
        } else {// [草稿]
            FriendDao.getInstance().updateFriendContent(
                    mLoginUserId,
                    mFriend.getUserId(),
                    "&8824" + str,
                    XmppMessage.TYPE_TEXT, TimeUtils.sk_time_current_time());
        }
        PreferenceUtils.putString(mContext, "WAIT_SEND" + mFriend.getUserId() + mLoginUserId, str);
    }

    /**
     * 本地显示一条领取通知
     *
     * @param openRedpacket
     */
    public void showReceiverRedLocal(OpenRedpacket openRedpacket) {
        // 本地显示一条领取通知
        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setFileSize(XmppMessage.TYPE_83);
        chatMessage.setFilePath(openRedpacket.getPacket().getId());
        chatMessage.setFromUserId(mLoginUserId);
        chatMessage.setFromUserName(mLoginNickName);
        chatMessage.setToUserId(mFriend.getUserId());
        chatMessage.setType(XmppMessage.TYPE_TIP);
        chatMessage.setContent(mContext.getString(R.string.red_received_self, openRedpacket.getPacket().getUserName()));
        chatMessage.setPacketId(UUID.randomUUID().toString().replaceAll("-", ""));
        chatMessage.setTimeSend(TimeUtils.sk_time_current_time());
        if (ChatMessageDao.getInstance().saveNewSingleChatMessage(mLoginUserId, mFriend.getUserId(), chatMessage)) {
            mChatMessages.add(chatMessage);
            mChatView.updateContent(true);
        }
    }

    // 单张图片压缩 拍照
    public void photograph(final File file) {
        Log.e("zq", "压缩前图片路径:" + file.getPath() + "压缩前图片大小:" + file.length() / 1024 + "KB");
        // 拍照出来的图片Luban一定支持，
        Luban.with(mContext)
                .load(file)
                .ignoreBy(100)     // 原图小于100kb 不压缩
                // .putGear(2)     // 设定压缩档次，默认三挡
                // .setTargetDir() // 指定压缩后的图片路径
                .setCompressListener(new OnCompressListener() { // 设置回调
                    @Override
                    public void onStart() {
                        Log.e("zq", "开始压缩");
                    }

                    @Override
                    public void onSuccess(File file) {
                        Log.e("zq", "压缩成功，压缩后图片位置:" + file.getPath() + "压缩后图片大小:" + file.length() / 1024 + "KB");
                        sendImage(file);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("zq", "压缩失败,原图上传");
                        sendImage(file);
                    }
                }).launch();// 启动压缩
    }

    public void sendPhoneAndVidio(List<String> pathList) {

        for (String path : pathList) {
            File file = new File(path);
            if (MediaFile.isVideoFileType(path)) {
                sendVideo(file);
            } else {
                sendImage(file);
            }
        }
    }

    // 多张图片压缩 相册
    public void album(ArrayList<String> stringArrayListExtra, boolean isOriginal) {
        if (isOriginal) {// 原图发送，不压缩
            Log.e("zq", "原图发送，不压缩，开始发送");
            for (int i = 0; i < stringArrayListExtra.size(); i++) {
                sendImage(new File(stringArrayListExtra.get(i)));
            }
            Log.e("zq", "原图发送，不压缩，发送结束");
            return;
        }

        List<File> fileList = new ArrayList<>();
        for (int i = 0; i < stringArrayListExtra.size(); i++) {
            // gif动图不压缩，
            if (stringArrayListExtra.get(i).endsWith("gif")) {
                fileList.add(new File(stringArrayListExtra.get(i)));
                stringArrayListExtra.remove(i);
            } else {
                // Luban只处理特定后缀的图片，不满足的不处理也不走回调，
                // 只能挑出来不压缩，
                List<String> lubanSupportFormatList = Arrays.asList("jpg", "jpeg", "png", "webp", "gif");
                boolean support = false;
                for (int j = 0; j < lubanSupportFormatList.size(); j++) {
                    if (stringArrayListExtra.get(i).endsWith(lubanSupportFormatList.get(j))) {
                        support = true;
                        break;
                    }
                }
                if (!support) {
                    fileList.add(new File(stringArrayListExtra.get(i)));
                    stringArrayListExtra.remove(i);
                }
            }
        }

        if (fileList.size() > 0) {
            for (File file : fileList) {// 不压缩的部分，直接发送
                sendImage(file);
            }
        }

        Luban.with(mContext)
                .load(stringArrayListExtra)
                .ignoreBy(100)// 原图小于100kb 不压缩
                .setCompressListener(new OnCompressListener() {
                    @Override
                    public void onStart() {
                        Log.e("zq", "开始压缩");
                    }

                    @Override
                    public void onSuccess(File file) {
                        sendImage(file);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }
                }).launch();// 启动压缩
    }


    public void upLoadChatList(String chatIds, String name) {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", mCoreManager.getSelfStatus().accessToken);
        params.put("messageIds", chatIds);
        params.put("userId", mLoginUserId);
        params.put("courseName", name);
        params.put("createTime", TimeUtils.sk_time_current_time() + "");
        DialogHelper.showDefaulteMessageProgressDialog(mContext);

        HttpUtils.get().url(mCoreManager.getConfig().USER_ADD_COURSE)
                .params(params)
                .build()
                .execute(new BaseCallback<Void>(Void.class) {

                    @Override
                    public void onResponse(ObjectResult<Void> result) {
                        DialogHelper.dismissProgressDialog();
                        mChatView.showToastMsg(mContext.getString(R.string.tip_create_cource_success));
                    }

                    @Override
                    public void onError(Call call, Exception e) {
                        DialogHelper.dismissProgressDialog();
                        ToastUtil.showErrorNet(mContext);
                    }
                });
    }

    /**
     * 获取公众号菜单&&获取好友在线状态
     */
    public void initFriendState() {
        if (mFriend.getIsDevice() == 1) {
            return;
        }

        Map<String, String> params = new HashMap<>();
        params.put("access_token", mCoreManager.getSelfStatus().accessToken);
        params.put("userId", mFriend.getUserId());

        HttpUtils.get().url(mCoreManager.getConfig().USER_GET_URL)
                .params(params)
                .build()
                .execute(new BaseCallback<User>(User.class) {
                    @Override
                    public void onResponse(ObjectResult<User> result) {
                        if (result.getResultCode() == 1 && result.getData() != null) {
                            User user = result.getData();
                            if (user.getUserType() == 2) {
                                // 公众号,获取公众号菜单
                                initSpecialMenu();
                                return;
                            }
                            String name = mFriend.getRemarkName();
                            if (TextUtils.isEmpty(name)) {
                                name = mFriend.getNickName();
                            }
                            switch (user.getOnlinestate()) {
                                case 0:
                                    mChatView.changeOnLineState(false);
                                    break;
                                case 1:
                                    mChatView.changeOnLineState(true);
                                    break;
                            }

                            if (user.getSettings().getOnlyAllowAttentionSendMsg() == 1) {
                                mChatView.onlyAllowAttentionSendMsg(true);
                            } else {
                                mChatView.onlyAllowAttentionSendMsg(false);
                            }

                            if (user.getFriends() != null) {// 更新消息免打扰状态 && 更新消息保存天数

                                FriendDao.getInstance().updateOfflineNoPushMsgStatus(mFriend.getUserId(),
                                        user.getFriends().getOfflineNoPushMsg());
                                FriendDao.getInstance().updateChatRecordTimeOut(mFriend.getUserId(),
                                        user.getFriends().getChatRecordTimeOut());
                            }
                        }
                    }

                    @Override
                    public void onError(Call call, Exception e) {
                        ToastUtil.showErrorNet(mContext);
                    }
                });
    }

    /**
     * 获取公众号菜单
     */
    public void initSpecialMenu() {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", mCoreManager.getSelfStatus().accessToken);
        params.put("userId", mFriend.getUserId());

        HttpUtils.get().url(mCoreManager.getConfig().USER_GET_PUBLIC_MENU)
                .params(params)
                .build()
                .execute(new ListCallback<PublicMenu>(PublicMenu.class) {
                    @Override
                    public void onResponse(ArrayResult<PublicMenu> result) {
                        List<PublicMenu> data = result.getData();
                        if (data != null && data.size() > 0) {
                            mChatView.fillRoomMenu(data);
                        }
                    }

                    @Override
                    public void onError(Call call, Exception e) {
                        ToastUtil.showErrorNet(mContext);
                    }
                });
    }

    /**
     * 是否离线&&重连
     */
    private boolean isAuthenticated() {
        boolean isLogin = mCoreManager.isLogin();
        if (!isLogin) {
            mCoreManager.autoReconnect(mContext);
        }
        // Todo 离线时发消息也不能return，自动重连...，让消息转圈(有重发)
        // return !isLogin;
        return false;
    }

    /**
     * 判断用户是否在黑名单中
     *
     * @return
     */
    private boolean isInBlackList() {
        List<Friend> blackList = FriendDao.getInstance().getAllBlacklists(mLoginUserId);
        for (Friend friend : blackList) {
            if (friend.getUserId().equals(mFriend.getUserId())) {
                return true;
            }
        }
        return false;
    }

    private UploadEngine.ImFileUploadResponse mUploadResponse = new UploadEngine.ImFileUploadResponse() {

        @Override
        public void onSuccess(String toUserId, ChatMessage message) {
            sendMsg(message);
        }

        @Override
        public void onFailure(String toUserId, ChatMessage message) {
            for (int i = 1; i < mChatMessages.size(); i++) {
                ChatMessage msg = mChatMessages.get(i);
                if (message.get_id() == msg.get_id()) {
                    msg.setMessageState(ChatMessageListener.MESSAGE_SEND_FAILED);
                    ChatMessageDao.getInstance().updateMessageSendState(mLoginUserId, mFriend.getUserId(),
                            message.get_id(), ChatMessageListener.MESSAGE_SEND_FAILED);
                    mChatView.updateContent(false);
                    break;
                }
            }
        }
    };


}

